\begin{tikzpicture}

	\definecolor{appcolor}        {rgb}{1,1,0.7}
	\definecolor{guestoscolor}    {rgb}{0.8,0.8,0.7}
	\definecolor{defaultcolor}    {rgb}{1,1,1}
	\definecolor{criticalcolor}   {rgb}{0.9,0.5,0.4}
	\definecolor{kernelcolor}     {rgb}{0.6,0.8,0.7}
	\definecolor{drivercolor}     {rgb}{0.6,0.7,0.8}

	\tikzstyle{treenode} = [component, path fading=flow fade, align=center,
	                        rounded corners=1, minimum height=6ex]

	\tikzstyle{service} = [draw=black, draw opacity=0.4, ball color=defaultcolor, fill opacity=0.2,
	                       rounded corners=0, shape=semicircle,
	                       inner sep=1.3ex, outer sep=0, above]

	\tikzstyle{appnode}     = [treenode, bottom color=appcolor]
	\tikzstyle{kernelnode}  = [treenode, bottom color=kernelcolor, minimum width=65ex]
	\tikzstyle{drivernode}  = [treenode, bottom color=drivercolor]
	\tikzstyle{muxnode}     = [treenode, bottom color=criticalcolor]
	\tikzstyle{guestosnode} = [treenode, bottom color=guestoscolor, top color=appcolor]

	%
	% Components
	%

	% core / init
	\node[kernelnode] (core) {Core / Init};

	\path (core.north) node[service, xshift=-24ex, scale=0.4] (irqservice) {};
	\path (irqservice) node[scale=0.7, yshift=-2ex] {IRQ};

	\path (core.north) node[service, xshift=-12ex, scale=0.4] (mmioservice) {};
	\path (mmioservice) node[scale=0.7, yshift=-2ex] {MMIO};

	% platform driver
	\node[drivernode, minimum width=19ex, above=4ex of core, xshift=-17.5ex] (platformdrv) {Platform Driver};
	\path (platformdrv.north) node[service, scale=0.4] (platformservice) {};
	\path (platformdrv.north) node[scale=0.7, yshift=-1.5ex] {Platform};

	% Terminal crosslink
	\node[muxnode, minimum width=19ex, above=4ex of core, xshift=13.5ex] (crosslink)  {Terminal crosslink};
	\path (crosslink.north) node[service, scale=0.4, xshift=10ex] (terminalservice) {};
	\path (terminalservice) node[scale=0.7, yshift=-2ex] {Terminal};
	\path (crosslink.north) node[service, scale=0.4, xshift=-10ex] (terminalservice2) {};
	\path (terminalservice2) node[scale=0.7, yshift=-2ex] {Terminal};

	% Modem manager
	\node[drivernode, minimum width=15ex, above=10ex of platformdrv] (modemman)  {Modem Manager};

	% UART drivers
	\node[drivernode, minimum width=15ex, above=10ex of crosslink, xshift=-10ex] (hostuartdrv)  {UART Driver};
	\node[drivernode, minimum width=15ex, above=10ex of crosslink, xshift=10ex] (modemuartdrv)  {UART Driver};

	%
	% Sessions
	%
	\tikzstyle{treesessionarrow} = [arrow, thick]
	\path[treesessionarrow] (irqservice  |- platformdrv.south)   -- (irqservice);
	\path[treesessionarrow] (mmioservice |- platformdrv.south)   -- (mmioservice);
	\path[treesessionarrow] (hostuartdrv.320) .. controls +(0,-5ex) and +(0ex,5ex) ..  (terminalservice2);
	\path[treesessionarrow] (modemuartdrv.320) .. controls +(0,-5ex) and +(0ex,5ex) ..  (terminalservice);
	\path[treesessionarrow] (hostuartdrv.220) .. controls +(0,-5ex) and +(5ex,5ex) ..  (platformservice);
	\path[treesessionarrow] (modemuartdrv.220) .. controls +(0,-5ex) and +(5ex,5ex) ..  (platformservice);
	\path[treesessionarrow] (platformservice |- modemman.south) -- (platformservice);

	%
	% UART connections
	%
	\draw[arrow, <->, densely dashed] (hostuartdrv.250) -- +(0,-35ex) node[below=1ex] { Host console };
	\draw[arrow, <->, densely dashed] (modemuartdrv.310) -- +(0,-35ex) node[below=1ex] { Modem control };

\end{tikzpicture}
